package com.zhj.estest.client.test;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhj.estest.pojo.User;
import org.apache.http.HttpHost;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.MaxAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.thymeleaf.util.AggregateCharSequence;

import java.io.IOException;

public class ESTest_Doc_Query_Client {



    public static void main(String[] args) throws IOException {
        RestHighLevelClient esClient = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost",9200, "http"))
        );

        // 1 查询索引中全部数据
        SearchRequest request = new SearchRequest();
        request.indices("user");
        SearchSourceBuilder query = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
        request.source(query);
        SearchResponse search = esClient.search(request, RequestOptions.DEFAULT);

        System.out.println(search.getHits());
        System.out.println(search.getTook());
        for (SearchHit hit : search.getHits()) {
            System.out.println(hit.getSourceAsString());
        }

        // 2 条件查询
        request = new SearchRequest();
        request.indices("user");
        query = new SearchSourceBuilder().query(QueryBuilders.termQuery("age", 30));
        request.source(query);
        search = esClient.search(request, RequestOptions.DEFAULT);

        System.out.println(search.getHits());
        System.out.println(search.getTook());
        for (SearchHit hit : search.getHits()) {
            System.out.println(hit.getSourceAsString());
        }

        // 3 分页查询
        request = new SearchRequest();
        request.indices("user");
        query = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
        query.from(1);
        query.size(3);
        request.source(query);
        search = esClient.search(request, RequestOptions.DEFAULT);

        System.out.println(search.getHits());
        System.out.println(search.getTook());
        for (SearchHit hit : search.getHits()) {
            System.out.println(hit.getSourceAsString());
        }

        // 4 排序
        request = new SearchRequest();
        request.indices("user");
        query = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
        query.sort("age", SortOrder.DESC);
        request.source(query);
        search = esClient.search(request, RequestOptions.DEFAULT);

        System.out.println(search.getHits());
        System.out.println(search.getTook());
        for (SearchHit hit : search.getHits()) {
            System.out.println(hit.getSourceAsString());
        }

        // 5 过滤字段
        request = new SearchRequest();
        request.indices("user");
        query = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
        String[] excludes = {"age"};
        String[] includes = {"name","age"};
        query.fetchSource(includes, excludes);
        request.source(query);
        search = esClient.search(request, RequestOptions.DEFAULT);

        System.out.println(search.getHits());
        System.out.println(search.getTook());
        for (SearchHit hit : search.getHits()) {
            System.out.println(hit.getSourceAsString());
        }

        // 6 组合查询
        request = new SearchRequest();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.matchQuery("age",20));
        boolQueryBuilder.must(QueryBuilders.matchQuery("sex","男"));
        request.indices("user");
        query = new SearchSourceBuilder().query(boolQueryBuilder);
        request.source(query);
        search = esClient.search(request, RequestOptions.DEFAULT);

        System.out.println(search.getHits());
        System.out.println(search.getTook());
        for (SearchHit hit : search.getHits()) {
            System.out.println(hit.getSourceAsString());
        }

        // 7 范围查询
        request = new SearchRequest();
        RangeQueryBuilder age = QueryBuilders.rangeQuery("age");
        age.gt(20);
        age.lt(80);
        query = new SearchSourceBuilder().query(age);
        request.source(query);
        search = esClient.search(request, RequestOptions.DEFAULT);

        System.out.println(search.getHits());
        System.out.println(search.getTook());
        for (SearchHit hit : search.getHits()) {
            System.out.println(hit.getSourceAsString());
        }

        // 8 范围查询
        request = new SearchRequest();
        request.indices("user");
        FuzzyQueryBuilder fuzziness = QueryBuilders.fuzzyQuery("name", "王").fuzziness(Fuzziness.ONE);
        query = new SearchSourceBuilder().query(fuzziness);
        request.source(query);
        search = esClient.search(request, RequestOptions.DEFAULT);

        System.out.println(search.getHits());
        System.out.println(search.getTook());
        for (SearchHit hit : search.getHits()) {
            System.out.println(hit.getSourceAsString());
        }

        // 9 高亮查询
        request = new SearchRequest();
        request.indices("user");
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "王五");
        query = new SearchSourceBuilder().query(termQueryBuilder);
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<font color='red'>");
        highlightBuilder.postTags("</font>");
        highlightBuilder.field("name");
        query.highlighter(highlightBuilder);
        request.source(query);
        search = esClient.search(request, RequestOptions.DEFAULT);

        System.out.println(search.getHits());
        System.out.println(search.getHits().getTotalHits());
        System.out.println(search.getTook());
        for (SearchHit hit : search.getHits()) {
            System.out.println(hit.getSourceAsString());
        }

        // 10 聚合查询
        request = new SearchRequest();
        request.indices("user");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        MaxAggregationBuilder field = AggregationBuilders.max("maxAge").field("age");
        searchSourceBuilder.aggregation(field);
        request.source(searchSourceBuilder);
        search = esClient.search(request, RequestOptions.DEFAULT);

        System.out.println(search.getHits());
        System.out.println(search.getHits().getTotalHits());
        System.out.println(search.getTook());
        for (SearchHit hit : search.getHits()) {
            System.out.println(hit.getSourceAsString());
        }

        // 11 分组查询
        request = new SearchRequest();
        request.indices("user");
        searchSourceBuilder = new SearchSourceBuilder();
        TermsAggregationBuilder fieldAge = AggregationBuilders.terms("ageGroup").field("age");
        searchSourceBuilder.aggregation(fieldAge);
        request.source(searchSourceBuilder);
        search = esClient.search(request, RequestOptions.DEFAULT);

        System.out.println(search.getHits());
        System.out.println(search.getHits().getTotalHits());
        System.out.println(search.getTook());
        for (SearchHit hit : search.getHits()) {
            System.out.println(hit.getSourceAsString());
        }

        esClient.close();
    }
}
